module ID(
    input [15:0] Instr,// From IF
    input [7:0] PC, //from Original PC
    
    output [7:0] Reg0_addr,// to Regfile
    output [7:0] Reg1_addr,// to Regfile
    output [7:0] Dst_addr,// to Regfile
    
    output [2:0] opcode,// to ALU and Branch unit
    output reg [7:0] offset,// TO branch unit
    
    output reg [7:0] NextPC,
    
    // the Control signals
    output mem_we, RegFile_we,
    
    output Reg0_sel, Reg1_sel,
    output PC_sel
    
);


    localparam [2:0] 
            add=3'b000,
            addi=3'b001,
            sub=3'b010,
            subi=3'b011,
            move=3'b100,
            movei=3'b101,
            beq=3'b110,
            blt=3'b111;
    
    reg [7:0] small_Instr;
    
    
    always @(Instr or PC) begin
    
    
        offset=8'b0;
        small_Instr=Instr[15:8];
        
        case (Instr[15:13])
        // 16-bits instruction
        addi , subi , movei , beq , blt: begin
            NextPC=PC+2;
            offset=Instr[7:0];
            
            
            
        end
        
        //8-bits instruction
        add , sub , move : begin
            NextPC=PC+1;            
        end
        
        default : begin
            $display("Error bad opcode!");
            $display("das");
            
            NextPC=8'b0;   
        end
                
        endcase
               
    end

        //Decoding
        assign opcode=small_Instr[7:5];
        assign Reg1_addr=small_Instr[4:3];
        assign Reg0_addr=small_Instr[2:1];
        assign Dst_addr=(small_Instr[0])? small_Instr[4:3] : small_Instr[2:1];
        
        //Control signals
        assign PC_sel = (opcode==beq || opcode==blt)? 1'b1 : 1'b0; // 1=from Branch unit, 0=from ID
        assign Reg0_sel = (Reg0_addr==2'b00)? 1'b1 : 1'b0;// 1=from memory, 0= from RegFile
        assign Reg1_sel = (opcode== addi || opcode==subi || opcode==movei)? 1'b1 : 1'b0;// 1=from immadiate, 0= from RegFile
        
        assign mem_we = ((opcode==add || opcode==sub || opcode==move) && Dst_addr==2'b00) ? 1'b1 : 1'b0; // 1=write back to Memory, 0= Not.   
        assign RegFile_we = (!(opcode==beq || opcode==blt) && !mem_we)? 1'b1 : 1'b0;

    
endmodule
